#include<iostream>
using namespace std;
class Date
{
public:
	friend ostream& operator<<(ostream& _cout, Date& d);//声明友元函数
	friend istream& operator>>(istream& _cin, Date& d);

	Date(int year = 1999, int month = 1, int day = 1)// 全缺省的构造函数
		:_year(year)
		,_month(month)
		,_day(day)//初始化列表	
	{
		if (!(year > 0 && (month > 0 && month < 13) && (day > 0 && day <= GetMonthDay(year, month))))
		{
			_year=1999;
			_month=1;
			_day=1;
		}
	}
	
	// 获取某年某月的天数
	int GetMonthDay(int year, int month)
	{
		int array[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
					 
		if (month == 2 && (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)))//判断是否是闰年
		{
			array[2]+=1;
		}
		return array[month];

	}
	void PrintDate()//打印年月日
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}


	// 拷贝构造函数
	Date(const Date& d)
		:_year(d._year)
		, _month(d._month)
		, _day(d._day)//初始化列表	
	{}

	Date& operator=(const Date& d)// 赋值运算符重载, // d2 = d3 -> d2.operator=(&d2, d3)
	{
		if (this !=  &d)////判断两个对象的地址是否相等，避免值相同的情况下重复操作
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;
	}

	~Date()// 析构函数
	{}

	Date& operator+=(int day)// 日期+=天数
	{
		if (day < 0)
		{
			return *this -= (-day);
		}//	*this = *this + (day)等价于	*this = *this - (-day);此时-day大于0

		_day += day;
		while (_day  > GetMonthDay(_year, _month))//while (_day += day > GetMonthDay(_year, _month))
		{
			_day -= GetMonthDay(_year, _month);
			_month++;
			if (_month == 13)
			{
				_year++;
				_month = 1;
			}
		}
		return *this;
	}

	Date& operator-=(int day)// 日期-=天数
	{
		if (day < 0)
		{
			return *this += (-day);
		}//*this = *this - (day)等价于	*this = *this + (-day);此时-day大于0


		_day -= day;//while (_day -= day < 0)
		while (_day <= 0)
		{
			_month--;
			if (_month == 0)
			{
				_year--;
				_month = 12;
			}
			_day += GetMonthDay(_year, _month);

		}
		return *this;
	}

	Date operator+(int day)// 日期+天数
	{
		if (day < 0)
		{
			return *this - (-day);
		}

		Date temp(*this);
		/*temp._day += day;
		while (temp._day  > GetMonthDay(temp._year, temp._month))
		{
			temp._day -= GetMonthDay(temp._year, temp._month);
			temp._month++;
			if (temp._month == 13)
			{
				temp._year++;
				temp._month = 1;
			}
		}
		return temp;*/
		//第二种写法:
		temp += day;
		return temp;



	}

	Date operator-(int day)// 日期-天数
	{
		if (day < 0)
		{
			return *this + (-day);
		}

		Date temp(*this);
		temp._day -= day;
		while (temp._day  <= 0)
		{
			temp._month--;
			if (temp._month == 0)
			{
				temp._year--;
				temp._month = 12;
			}
			temp._day += GetMonthDay(temp._year, temp._month);
			
		}
		return temp;
	}


	Date& operator++()// 前置++
	{
		return *this += 1;
	}

	
	//后置++,为了和前置++区分开，括号内加一个int进行区分
	Date operator++(int)// 后置++
	{//返回临时对象，返回值不能是引用，不然引用了一个临时对象，
	//函数结束时，临时对象会被销毁，此时引用了一个非法变量
		Date temp(*this);
		*this += 1;
		return temp;
	}

	Date operator--(int)// 后置--
	{
		Date temp(*this);
		*this -= 1;
		return temp;
	}

	Date& operator--()// 前置--
	{
		return *this -= 1;
	}

	bool operator>(const Date& d)// >运算符重载
	{
		return (_year > d._year || (_year == d._year && _month > d._month) ||
			(_year == d._year && _month == d._month && _day > d._day));
	}

	bool operator==(const Date& d)// ==运算符重载
	{
		return (_year == d._year && _month == d._month && _day == d._day);
	}

	bool operator != (const Date& d)// !=运算符重载
	{
		return !(*this == d);//不等于是等于的对立面
	}
	bool operator < (const Date& d)// <运算符重载
	{
		return !( *this > d  ||  *this == d );//不大不等于不就小于了
	}

	bool operator >= (const Date& d)	// >=运算符重载
	{
		return !(*this < d);
	}

	bool operator <= (const Date& d)// <=运算符重载
	{
		return !(*this > d);
	}

	int operator-(const Date& d)const// 日期-日期 返回天数
	{
		int count = 0;
		Date max = *this;
		Date min = d;
		if (max < min)
		{
			max = d;
			min = *this;
		}
		while(max != min)
		{
			min++;
			count++;
		}

		return count;
	}

private:
	int _year;
	int _month;
	int _day;
};
ostream& operator<<(ostream& _cout, Date& d)
{
	_cout << d._year << "-" << d._month << "-" << d._day;
	return _cout;
}
istream& operator>>(istream& _cin, Date& d)
{
	_cin >> d._year >> d._month >> d._day;
	return _cin;
}


int main()
{
	Date d1(2022, 10, 15);
	Date d2(2022,6,6);
	int a = (d1 - d2);
	cout <<  a<< endl;
	cout << "--------------------------------" << endl;
	Date d3,d4;
	d3 = d4 = d1;
	/*cin >> d3>>d4;
	cout << d3 <<"----------------------------" << d4 << endl;*/
	Date b = (d3 - 155);
	cout <<"d3="<< d3 << endl;
	Date c = (d4 -= 155);
	cout <<"d4="<< d4 << endl;
	Date d5(2022, 10, 31);
	d5++;
	cout << "d5=" << d5 << endl;
	cout << (d5 > d1) << endl;
	cout << "--------------------------------" << endl;
	cout << (d2 > d1) << endl;
	//d5--;
	//--d5;
	//++d5;
	//d5++;
	/*Date d6(2000, 12, 31);
	++d6;
	d6++;
	d6--;
	--d6;*/
	//Date d6(2000, 2, 28);
	//++d6;
	//d6++;
	//d6--;
	//--d6; 
	Date nb = (d5 + 166);
	cout << nb << endl;
	
	Date ss = (d5 - 166);
	cout << ss << endl;
	//d5.PrintDate();
	return 0;
 }